package sdmakerz_v1.coresyntax.generator

import java.util.HashMap
import java.util.HashSet
import java.util.Set
import sdmakerz_v1.coresyntax.generator.interfaces.IDiagramRefData
import sdmakerz_v1.coresyntax.sDMakerV1.Diagram
import sdmakerz_v1.coresyntax.sDMakerV1.DiagramRef
import sdmakerz_v1.coresyntax.sDMakerV1.Lifeline
import sdmakerz_v1.coresyntax.sDMakerV1.Binding

/** Une classe qui facilite le recuperation les informations 
 *  de renommage pour les diagrammes referes.
 *  Il faut savoir que le context contient toujours des donnees 
 *  de references. Par exemple quand on genere une declaration d 'objet 
 *  a la racine de la description, on demande quand meme au context son 
 *  nom reel (meme si celui-ci coincide avec l'ancien). Dans ce cas la, 
 *  le context rendra le meme nom (Voir methode init).
 * 
 *  @author pstl-team
 */
class DiagramRefDataImpl implements IDiagramRefData {
	private HashMap<String, String> bindings;
	private String diagNewName;
	
	/* ****************** *
     * ** INITIALIZERS ** *
     * ****************** */

	/**
	 * @param d: le diagramme qui contient la reference
	 * @param ref la reference 
	 * @param refData si on traite deja une reference
	 *                on propage les anciennes information de renommage.
	 *                C'est refData qui contient ces informations.
	 * @param diagNewName, util pour eviter les conflits lors de la creation
	 *                     du meme diagramme mais evalue.
	 */
	override void init(
		   Diagram d, 
		   DiagramRef ref,
		   IDiagramRefData refData,
		   String diagNewName){
		
		bindings= new HashMap<String, String>();
		this.diagNewName= diagNewName;
		
		if(ref == null){ //diagram classique
			for(elt : d.diagram_elts){
				if(elt instanceof Lifeline){
					var l= (elt as Lifeline);
					bindings.put(l.name, l.name);
				}
			}
		}
		else{
			for(Binding binding: ref.bindings){
				/* on veux retrouver directement le
				   nouveau nom a partir de l'ancien */
				bindings.put(binding.to, binding.from);	
				println("bindings "+binding.to+" with "+binding.from)
			}
		}
		
		if(refData != null){ 
		 /* Propagation: 
		  * Les elements "from" de cette Reference doivent provenir
		  * des elements from de refData et non plus de ceux du diagramme 
		  * courant. */
		  
		  var Set<String> keySet= new HashSet<String>(bindings.keySet);

		  for(String key : keySet){
		  	var String value= bindings.get(key);
		  	bindings.remove(key);
		  	bindings.put(key, refData.getNewName(value));
		  	println("finally "+key+" with "+refData.getNewName(value))
		  }
		}
	}
	
	
	
    /* ************* *
     * ** GETTERS ** *
     * ************* */
     
    override String diagNewName(){
		return diagNewName;
	}
	
	override String getNewName(String oldName){
		var String newName= null;
		
		for(String key : bindings.keySet){
			if(key.compareTo(oldName)==0){
				newName= bindings.get(key);
			}
		}
		
		return newName;
	}
	
//	def Set<String> keySet(){
//		return bindings.keySet;
//	}
}